// Copyright (c) XiGuan 2023
// Author： xiguan
// Email: xiguan.teng@qq.com
// Create on 2023/11/22
// TODO:
//

#ifndef WEBSERVER_SERVER_WEBSERVER_H
#define WEBSERVER_SERVER_WEBSERVER_H

#include <Epoller.h>
#include <HeapTimer.h>
#include <HttpConn.h>
#include <Log.h>
#include <SqlConnPool.h>
#include <SqlConnRAII.h>
#include <ThreadPool.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <unistd.h>

#include <unordered_map>

class WebServer {
 private:
  int port_;
  bool open_linger_;
  int timeout_ms_;
  bool is_close_;
  int listen_fd_;
  char *src_dir_;

  uint32_t listen_event_;
  uint32_t conn_event_;

  std::unique_ptr<HeapTimer> timer_;
  std::unique_ptr<ThreadPool> threadpool_;
  std::unique_ptr<Epoller> epoller_;

  std::unordered_map<int, HttpConn> users_;

  static const int MAX_FD_ = 65536;

 public:
  WebServer(int port, int trigMode, int timeoutMS, bool OptLinger, int sqlPort,
            const char *sqlUser, const char *sqlPwd, const char *dbName,
            int connPoolNum, int threadNum, bool openLog, int logLevel,
            int logQueSize);

  ~WebServer();

  void start();

 private:

  bool InitSocket_();
  void InitEventMode_(int trigMode);
  void AddClient_(int fd, sockaddr_in addr);

  void DealListen_();
  void DealWrite_(HttpConn *client);
  void DealRead_(HttpConn *client);

  void SendError_(int fd, const char *info);
  void ExtentTime_(HttpConn *client);
  void CloseConn_(HttpConn *client);

  void OnRead_(HttpConn *client);
  void OnWrite_(HttpConn *client);
  void OnProcess(HttpConn *client);

  static int SetFdNonblock(int fd);
};

#endif  // WEBSERVER_SERVER_WEBSERVER_H
